home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Presentations / Presentations ’92 / PatchWorks Kit / <PatchWorks++> / PatchAgent.a < prev    next >
Encoding:
Text File  |  1992-05-15  |  2.1 KB  |  75 lines  |  [TEXT/MPS ]

  1. ;
  2. ;    PatchAgent.a
  3. ;
  4. ;    Universal patch glue for PatchWorks. MPW Assembler version.
  5. ;
  6. ;    by Patrick C. Beard & Mouse Herrel.
  7. ;
  8. ;
  9.     INCLUDE    'Traps.a'
  10.     INCLUDE 'Patch.a'                                ; bring in record definitions.
  11. ;
  12.     STRING    ASIS
  13. ;
  14. FP        EQU        a6
  15. ;
  16. ;    PatchAgent
  17. ;
  18. ;    This routine is meant to be called from a small stub of code that has
  19. ;    this C structure:
  20. ;
  21. ;
  22. ;    struct PatchStub {
  23. ;        short jsr_jmp;        // absolute jsr/jmp instruction.
  24. ;        long address;        // points to the glue code.
  25. ;        Patch* instance;    // pointer to instance.
  26. ;    };
  27. ;
  28. ;    This allows the patch agent code to pull out the instance by the return address
  29. ;    and reduce the size of the per patch overhead.
  30. ;
  31. PatchAgent    PROC    EXPORT
  32.         WITH    Patch                                ; use the Patch object.
  33.         link    FP, #0
  34.         movem.l    d0-d2/a0-a1/a4-a5, -(sp)            ; save the registers.
  35.         move.l    4(FP), a0                            ; return address points into PatchStub
  36.         move.l    (a0), a0                            ; get pointer to Patch out of it.
  37.         move.l    itsOld(a0), 4(FP)                    ; put old trap address on stack.
  38.         move.l    itsBehavior(a0), d0                    ; get the behavior.
  39.         
  40.         clr.l    -(sp)                                ; save room for stack adjustment.
  41.         move.l    a0, -(sp)                            ; pass Patch instance.
  42.         
  43.         move.l    itsGlobals(a0), GLOBALS                ; set up the patch's globals.
  44.         move.l    d0, a0
  45.         jsr        (a0)                                ; call the behavior.
  46.         
  47.         add.l    #4, sp                                ; remove patch parameter we pushed.
  48.         move.l    (sp)+, d0                            ; see if we're 
  49.         beq.s    @restore
  50.         
  51.         ; we're heading off the patch, return to caller.
  52.         ; this is accomplished by copying the return address back before where the
  53.         ; parameters are, and adjusting the frame pointer to remove the caller's
  54.         ; arguments if there are any.
  55.         ;
  56.         ; note, the 36 & 28 are hard coded offsets to the link & return addresses.
  57.         ; They are derived from the PatchFrame structure in Patch.h.
  58.         ; in the case of exceptions, the caller is at 38 because of the status value.
  59.         ; therefore, we can't really tail patch exceptions with this glue.
  60.         
  61.         move.l    d0, FP
  62.         move.l    36(sp), -(FP)                        ; get caller's return address.
  63.         move.l    28(sp), -(FP)                        ; get old value of FP so unlk works.
  64.  
  65. @restore
  66.         movem.l    (sp)+, d0-d2/a0-a1/a4-a5
  67.         unlk    FP
  68.         rts
  69.  
  70. @macsbug        
  71.         dc.b    $80 + $A, 'PatchAgent'                ; macsbug symbol.
  72.  
  73.         ENDP
  74. ;
  75.